@objectstack/runtime 7.5.0 → 7.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -3773,6 +3773,46 @@ var _HttpDispatcher = class _HttpDispatcher {
3773
3773
  }
3774
3774
  return { handled: false };
3775
3775
  }
3776
+ /**
3777
+ * Handles in-app notification requests (ADR-0030) — the
3778
+ * `/api/v1/notifications` surface backed by the messaging service's inbox
3779
+ * read API. Reads the L5 `sys_inbox_message` + `sys_notification_receipt`
3780
+ * join; mark-read upserts the receipt keyed `(notification_id, user_id,
3781
+ * channel:'inbox')`. The routes are `auth: true`, so an authenticated user
3782
+ * is required.
3783
+ *
3784
+ * Routes (path is the sub-path after `/notifications`):
3785
+ * GET '' → listInbox (query: read, type, limit)
3786
+ * POST /read → markRead (body: { ids: string[] })
3787
+ * POST /read/all → markAllRead
3788
+ */
3789
+ async handleNotification(path, method, body, query, context) {
3790
+ const service = await this.resolveService(import_system2.CoreServiceName.enum.notification, context.environmentId);
3791
+ if (!service || typeof service.listInbox !== "function") return { handled: false };
3792
+ const userId = context.executionContext?.userId;
3793
+ if (!userId) {
3794
+ return { handled: true, response: this.error("Authentication required", 401) };
3795
+ }
3796
+ const m = method.toUpperCase();
3797
+ const subPath = path.replace(/^\/+/, "").replace(/\/+$/, "");
3798
+ if (subPath === "" && m === "GET") {
3799
+ const read = query?.read === void 0 ? void 0 : String(query.read) === "true";
3800
+ const limit = query?.limit ? Number(query.limit) : void 0;
3801
+ const type = query?.type ? String(query.type) : void 0;
3802
+ const result = await service.listInbox(userId, { read, type, limit });
3803
+ return { handled: true, response: this.success(result) };
3804
+ }
3805
+ if (subPath === "read" && m === "POST") {
3806
+ const ids = Array.isArray(body?.ids) ? body.ids.map((x) => String(x)) : [];
3807
+ const result = await service.markRead(userId, ids);
3808
+ return { handled: true, response: this.success(result) };
3809
+ }
3810
+ if (subPath === "read/all" && m === "POST") {
3811
+ const result = await service.markAllRead(userId);
3812
+ return { handled: true, response: this.success(result) };
3813
+ }
3814
+ return { handled: false };
3815
+ }
3776
3816
  /**
3777
3817
  * Handles i18n requests
3778
3818
  * path: sub-path after /i18n/
@@ -4653,6 +4693,9 @@ var _HttpDispatcher = class _HttpDispatcher {
4653
4693
  if (cleanPath.startsWith("/analytics")) {
4654
4694
  return this.handleAnalytics(cleanPath.substring(10), method, body, context);
4655
4695
  }
4696
+ if (cleanPath.startsWith("/notifications")) {
4697
+ return this.handleNotification(cleanPath.substring(14), method, body, query, context);
4698
+ }
4656
4699
  if (cleanPath.startsWith("/packages")) {
4657
4700
  return this.handlePackages(cleanPath.substring(9), method, body, query, context);
4658
4701
  }